using Newtonsoft.Json;
using LiJ.Common.Core;
using LiJ.Common.Extention;
using LiJ.Common.Plugs.CachePlug;
using LiJ.Http.Mos;
using LiJ.Framework.Official.Basic.Mos;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace LiJ.Framework.Official
{
	/// <summary>
	/// 微信公号接口基类
	/// </summary>
	public class WxOffBaseApi : WxBaseApi
	{
		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="config"></param>
		public WxOffBaseApi(AppConfig config)
			: base(config)
		{
		}

		/// <summary>
		/// 获取微信服务器列表
		/// </summary>
		/// <returns></returns>
		public async Task<WxIpListResp> GetWxIpListAsync()
		{
			var req = new LHttpRequest
			{
				HttpMothed = HttpMothed.Get,
				AddressUrl = "https://api.weixin.qq.com" + "/cgi-bin/getcallbackip"
			};
			return await this.RestCommonOffcialAsync<WxIpListResp>(req, null);
		}

		/// <summary>
		///   获取公众号的AccessToken
		///     【首先从缓存中获取，如果没有再从远程获取】
		/// </summary>
		/// <returns></returns>
		public virtual async Task<WxOffAccessTokenResp> GetAccessTokenFromCacheAsync()
		{
			if (base.ApiConfig.OperateMode == AppOperateMode.ByAgent)
			{
				Func<AppConfig, string> accessTokenFromAgentFunc = WxOfficialConfigProvider.AccessTokenFromAgentFunc;
				string text = accessTokenFromAgentFunc?.Invoke(base.ApiConfig);
				if (string.IsNullOrEmpty(text))
				{
					throw new ArgumentNullException("access_token", "access_token值未发现，请检查 WxOfficialConfigProvider 下 AccessTokenFromAgentFunc 委托是否为空或者返回值不正确！");
				}
				return new WxOffAccessTokenResp
				{
					access_token = text
				};
			}
			string mOffcialAccessTokenKey = string.Format("social_wx_offcial_accesstoken_{0}", base.ApiConfig.AppId);
			WxOffAccessTokenResp wxOffAccessTokenResp = CacheUtil.Get<WxOffAccessTokenResp>(mOffcialAccessTokenKey, base.ModuleName);
			if (wxOffAccessTokenResp != null && wxOffAccessTokenResp.expires_date >= DateTime.Now.ToUtcSeconds())
			{
				return wxOffAccessTokenResp;
			}
			wxOffAccessTokenResp = await this.GetAccessTokenFromWxAsync();
			if (!wxOffAccessTokenResp.IsSuccess())
			{
				return wxOffAccessTokenResp;
			}
			wxOffAccessTokenResp.expires_date = DateTime.Now.ToUtcSeconds() + wxOffAccessTokenResp.expires_in - 600;
			CacheUtil.AddOrUpdate(mOffcialAccessTokenKey, wxOffAccessTokenResp, TimeSpan.FromSeconds(wxOffAccessTokenResp.expires_in - 600), null, ModuleName);
			return wxOffAccessTokenResp;
		}

		/// <summary>
		/// 从微信服务器获取AccessToken，请注意访问速率控制，正常情况请访问： 【GetAccessTokenFromCacheAsync】
		/// </summary>
		/// <returns></returns>
		public async Task<WxOffAccessTokenResp> GetAccessTokenFromWxAsync()
		{
			var request = new LHttpRequest
			{
				AddressUrl = string.Format("{0}/cgi-bin/token?grant_type=client_credential&appid={1}&secret={2}", "https://api.weixin.qq.com", base.ApiConfig.AppId, base.ApiConfig.AppSecret),
				HttpMothed = HttpMothed.Get
			};
			return await base.RestCommonJson<WxOffAccessTokenResp>(request, null);
		}

		/// <summary>
		///   公众号主要Rest请求接口封装
		///      主要是预处理accesstoken赋值
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="req"></param>
		/// <param name="client">自定义 HttpClient </param>
		/// <returns></returns>
		protected async Task<T> RestCommonOffcialAsync<T>(LHttpRequest req, HttpClient client = null) where T : WxBaseResp, new()
		{
			WxOffAccessTokenResp wxOffAccessTokenResp = await this.GetAccessTokenFromCacheAsync();
			if (!wxOffAccessTokenResp.IsSuccess())
			{
				return ResultMoMap.ConvertToResult<T>(wxOffAccessTokenResp);
			}
			req.RequestSet = delegate(HttpRequestMessage r)
			{
				r.Headers.Add("Accept", "application/json");
				if (r.Content != null)
				{
					r.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json")
					{
						CharSet = "UTF-8"
					};
				}
			};
			req.AddressUrl = req.AddressUrl + ((req.AddressUrl.IndexOf('?') > 0) ? "&" : "?") + "access_token=" + wxOffAccessTokenResp.access_token;
			return await base.RestCommonJson<T>(req, client);
		}

		/// <summary>
		///   下载文件方法
		/// </summary>
		protected static async Task<WxFileResp> DownLoadFileAsync(HttpResponseMessage resp)
		{
			if (!resp.IsSuccessStatusCode)
			{
				return new WxFileResp
				{
					Ret = 1420,
					Msg = "当前请求失败！"
				};
			}
			string mediaType = resp.Content.Headers.ContentType.MediaType;
			if (!mediaType.Contains("application/json"))
			{
				WxFileResp wxFileResp = new WxFileResp
				{
					content_type = mediaType
				};
				WxFileResp wxFileResp2 = wxFileResp;
				wxFileResp2.file = await resp.Content.ReadAsByteArrayAsync();
				return wxFileResp;
			}
			return JsonConvert.DeserializeObject<WxFileResp>(await resp.Content.ReadAsStringAsync());
		}
	}
}
